home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-08-16 | 15.8 KB | 481 lines | [TEXT/MPS ] |
- //========================================================================================
- //
- // File: EditCmd.cpp
- // Release Version: $ ODF 1 $
- //
- // Author: Laurent Delamare
- //
- // Copyright: (c) 1993 - 1996 by Apple Computer, Inc., all rights reserved.
- //
- //========================================================================================
-
- #include "Form.hpp"
-
- #ifndef EDITCMD_H
- #include "EditCmd.h"
- #endif
-
- #ifndef FWEDVIEW_H
- #include "FWEdView.h"
- #endif
-
- #ifndef FWFRAME_H
- #include "FWFrame.h"
- #endif
-
- #ifndef FWPART_H
- #include "FWPart.h"
- #endif
-
- #ifndef FWUTIL_H
- #include "FWUtil.h"
- #endif
-
- //========================================================================================
- // RunTime Info
- //========================================================================================
-
- #ifdef FW_BUILD_MAC
- #pragma segment odfform
- #endif
-
- FW_DEFINE_AUTO(CEditViewCommand)
-
- //========================================================================================
- // class FW_CEditViewCommand
- //========================================================================================
-
- //----------------------------------------------------------------------------------------
- // CEditViewCommand constructor
- //----------------------------------------------------------------------------------------
- CEditViewCommand::CEditViewCommand(Environment* ev,
- ODCommandID commandID,
- FW_CFrame* frame,
- FW_Boolean canUndo)
- : FW_CClipboardCommand(ev, commandID, frame, canUndo),
- FW_MReceiver(),
- fOwnsSelection(false),
- fEditView(0),
- fStartOffset(0),
- fEndOffset(0)
- {
- }
-
- //----------------------------------------------------------------------------------------
- // CEditViewCommand destructor
- //----------------------------------------------------------------------------------------
-
- CEditViewCommand::~CEditViewCommand()
- {
- if (fOwnsSelection)
- delete fSelection; // Selection was created on the fly in DoMenu
- }
-
- //----------------------------------------------------------------------------------------
- // CEditViewCommand::SetEditView
- //----------------------------------------------------------------------------------------
- // SetEditView must be called right after the creation of the CEditViewCommand in order
- // to initialize the fEditView attribut because FW_CFrame::NewClipboardCommand doesn't let
- // us pass arguments. See CScrollEdit::DoMenu().
-
- void CEditViewCommand::SetEditView(FW_CEditView* editView)
- {
- fEditView = editView;
-
- // [LSD] work-around to notify & disable the command when the edit view is deleted
- // See CEditViewCommand::HandleNotification
- AddInterest(FW_CInterest(editView, FW_kNotifierDeletedMsg));
- }
-
- //----------------------------------------------------------------------------------------
- // CEditViewCommand::HandleNotification
- //----------------------------------------------------------------------------------------
- //
- void CEditViewCommand::HandleNotification(Environment* ev, const FW_CNotification& notification)
- {
- if (notification.GetMessage() == FW_kNotifierDeletedMsg)
- {
- // [LSD] The edit view associated with this command has been deleted. We cannot
- // delete the command ourselves, it belongs to OpenDoc Undo stack, but we must
- // disable it to avoid any trouble in RedoIt & UndoIt.
- fEditView = 0;
- }
- }
-
- //----------------------------------------------------------------------------------------
- // CEditViewCommand::PreCommand
- //----------------------------------------------------------------------------------------
-
- void CEditViewCommand::PreCommand(Environment* ev)
- {
- ODCommandID id = GetCommandID(ev);
-
- if ((id == kODCommandCopy) || (id == kODCommandCut))
- fEditView->DoTECommand(ev, kODCommandCopy, false); // Tell TE to copy the text
- }
-
- //----------------------------------------------------------------------------------------
- // CEditViewCommand::CommandDone
- //----------------------------------------------------------------------------------------
- /*
- void CEditViewCommand::CommandDone(Environment* ev)
- {
- // If fEditView belongs to your part's content you may want to notify it of the change
- switch (GetCommandID(ev))
- {
- case kODCommandCut:
- case kODCommandPaste:
- case kODCommandClear:
- fEditView->Notify(ev, CEditNotification(fEditView));
- }
- }
- */
-
- //----------------------------------------------------------------------------------------
- // CEditViewCommand::SaveUndoState
- //----------------------------------------------------------------------------------------
- void CEditViewCommand::SaveUndoState(Environment* ev)
- {
- switch (GetCommandID(ev))
- {
- case kODCommandCut:
- case kODCommandClear:
- fPastedText = fEditView->GetSelectedText(ev);
- fEditView->GetSelectionRange(ev, fStartOffset, fEndOffset);
- break;
-
- case kODCommandPaste:
- fSavedText = fEditView->GetSelectedText(ev);
- fEditView->GetSelectionRange(ev, fStartOffset, fEndOffset);
- break;
- }
- }
-
- //----------------------------------------------------------------------------------------
- // CEditViewCommand::SaveRedoState
- //----------------------------------------------------------------------------------------
- void CEditViewCommand::SaveRedoState(Environment* ev)
- {
- if (GetCommandID(ev) == kODCommandPaste)
- {
- CEditViewSelContent* selContent = (CEditViewSelContent*)fSelection->GetSelectedContent(ev);
- fPastedText = selContent->GetInternalizedText(ev);
- }
- }
-
- //----------------------------------------------------------------------------------------
- // CEditViewCommand::UndoIt
- //----------------------------------------------------------------------------------------
-
- void CEditViewCommand::UndoIt(Environment* ev)
- {
- FW_CClipboardCommand::UndoIt(ev); // call inherited
-
- // Don't do anything if command is disabled
- if (fEditView == NULL)
- return;
-
- switch (GetCommandID(ev))
- {
- case kODCommandCut:
- case kODCommandClear:
- this->RestoreText(ev);
- break;
-
- case kODCommandPaste:
- this->RemoveAndRestoreText(ev, fPastedText.GetByteLength(), fSavedText);
- break;
- }
- }
-
- //----------------------------------------------------------------------------------------
- // CEditViewCommand::RedoIt
- //----------------------------------------------------------------------------------------
- void CEditViewCommand::RedoIt(Environment* ev)
- {
- FW_CClipboardCommand::RedoIt(ev); // call inherited
-
- // Don't do anything if command is disabled
- if (fEditView == NULL)
- return;
-
- switch (GetCommandID(ev))
- {
- case kODCommandCut:
- case kODCommandClear:
- this->RemoveText(ev);
- break;
-
- case kODCommandPaste:
- this->RemoveAndRestoreText(ev, fSavedText.GetByteLength(), fPastedText);
- break;
- }
- }
-
- //----------------------------------------------------------------------------------------
- // CEditViewCommand::RemoveText
- //----------------------------------------------------------------------------------------
-
- void CEditViewCommand::RemoveText(Environment* ev)
- {
- FW_ASSERT(fEditView);
-
- fEditView->SelectText(ev, fStartOffset, fEndOffset);
- fEditView->DoTECommand(ev, kODCommandClear, false);
-
- // If fEditView belongs to your part's content you may want to notify it of the change
- // fEditView->Notify(ev, CEditNotification(fEditView));
- }
-
- //----------------------------------------------------------------------------------------
- // CEditViewCommand::RestoreText
- //----------------------------------------------------------------------------------------
-
- void CEditViewCommand::RestoreText(Environment* ev)
- {
- FW_ASSERT(fEditView);
-
- // Insert the saved text back into the EditView
- fEditView->InsertText(ev, fPastedText, fStartOffset);
-
- // If fEditView belongs to your part's content you may want to notify it of the change
- // fEditView->Notify(ev, CEditNotification(fEditView));
- }
-
- //----------------------------------------------------------------------------------------
- // CEditViewCommand::RemoveAndRestoreText
- //----------------------------------------------------------------------------------------
-
- void CEditViewCommand::RemoveAndRestoreText(Environment* ev, FW_ByteCount bytesToRemove,
- const FW_CString& textToRestore)
- {
- FW_ASSERT(fEditView);
-
- // Remove designated text
- fEditView->SelectText(ev, fStartOffset, fStartOffset+(short)bytesToRemove);
- fEditView->DoTECommand(ev, kODCommandClear, false);
-
- // Restore the text
- fEditView->InsertText(ev, textToRestore, fStartOffset);
-
- // If fEditView belongs to your part's content you may want to notify it of the change
- // fEditView->Notify(ev, CEditNotification(fEditView));
- }
-
- #pragma mark -
- //========================================================================================
- // CLASS CEditViewSelection
- //========================================================================================
-
- FW_DEFINE_AUTO(CEditViewSelection)
-
- //---------------------------------------------------------------------------------------
- // CEditViewSelection constructor
- //---------------------------------------------------------------------------------------
-
- CEditViewSelection::CEditViewSelection(Environment* ev, FW_CEditView* editview) :
- FW_CSelection(ev, false, false),
- fSelectedContent(NULL)
- {
- fSelectedContent = FW_NEW(CEditViewSelContent, (ev, editview));
- }
-
- //---------------------------------------------------------------------------------------
- // CEditViewSelection destructor
- //---------------------------------------------------------------------------------------
-
- CEditViewSelection::~CEditViewSelection()
- {
- delete fSelectedContent;
- }
-
- //---------------------------------------------------------------------------------------
- // CEditViewSelection::ClearSelection
- //---------------------------------------------------------------------------------------
-
- void CEditViewSelection::ClearSelection(Environment* ev)
- {
- fSelectedContent->ClearSelectedText(ev);
- }
-
- //---------------------------------------------------------------------------------------
- // CEditViewSelection::CloseSelection
- //---------------------------------------------------------------------------------------
-
- void CEditViewSelection::CloseSelection(Environment* ev)
- {
- fSelectedContent->UnselectText(ev);
- }
-
- //---------------------------------------------------------------------------------------
- // CEditViewSelection::IsEmpty
- //---------------------------------------------------------------------------------------
-
- FW_Boolean CEditViewSelection::IsEmpty(Environment* ev) const
- {
- return fSelectedContent->IsEmpty(ev);
- }
-
- //---------------------------------------------------------------------------------------
- // CEditViewSelection::SelectAll
- //---------------------------------------------------------------------------------------
-
- void CEditViewSelection::SelectAll(Environment* ev)
- {
- FW_UNUSED(ev);
- // This function is handled by the current EditView
- }
-
- #pragma mark -
- //========================================================================================
- // CEditViewSelContent class
- //========================================================================================
-
- FW_DEFINE_AUTO(CEditViewSelContent)
-
- //----------------------------------------------------------------------------------------
- // CEditViewSelContent constructor
- //----------------------------------------------------------------------------------------
- CEditViewSelContent::CEditViewSelContent(Environment* ev, FW_CEditView* editview) :
- FW_CContent(ev, editview->GetFrame(ev)->GetPart(ev)),
- fEditView(editview)
- {
- }
-
- //----------------------------------------------------------------------------------------
- // CEditViewSelContent destructor
- //----------------------------------------------------------------------------------------
-
- CEditViewSelContent::~CEditViewSelContent()
- {
- }
-
- //----------------------------------------------------------------------------------------
- // CEditViewSelContent::Externalize
- //----------------------------------------------------------------------------------------
- void CEditViewSelContent::Externalize( Environment* ev,
- ODStorageUnit* storageUnit,
- FW_EStorageKinds storageKind,
- FW_CCloneInfo* cloneInfo)
- {
- FW_UNUSED(cloneInfo);
- FW_UNUSED(storageKind);
-
- // Externalize in order of fidelity: ODIText, 'TEXT'
- FW_CString selectedText = fEditView->GetSelectedText(ev);
-
- /* This doesn't work, because when I Internalize the text it's in the form:
- length word, char, etc.
- where each character takes up a word instead of a byte.
- // Write the selected string as an ODIText
- ODSetITextProp(ev, storageUnit, kODPropContents, kODIntlText, selectedText.RevealODIText());
- */
-
- // Write the selected string in Mac 'TEXT' format
- FW_SUAddPropValue(ev, storageUnit, kODPropContents, FW_CPart::gMacTEXTDataType);
- FW_PStorageUnitSink suSink(ev, storageUnit, kODPropContents, FW_CPart::gMacTEXTDataType);
- FW_CWritableStream stream(suSink);
- stream.Write(selectedText.RevealBuffer(), selectedText.GetByteLength());
- }
-
- //----------------------------------------------------------------------------------------
- // CEditViewSelContent::Internalize
- //----------------------------------------------------------------------------------------
-
- FW_Boolean CEditViewSelContent::Internalize(Environment* ev,
- ODStorageUnit* sourceSU,
- FW_EStorageKinds storageKind,
- FW_CCloneInfo* cloneInfo)
- {
- FW_UNUSED(cloneInfo);
- FW_UNUSED(storageKind);
- FW_ASSERT(fEditView);
-
- FW_Boolean internalized = false;
- FW_CString selectedText;
-
- // Compute the maximum number of characters that can be added to the edit view
- short startSel, endSel;
- fEditView->GetSelectionRange(ev, startSel, endSel);
- FW_ByteCount notSelectedChars = fEditView->GetTextLength(ev) - (endSel - startSel);
- if (notSelectedChars >= fEditView->GetMaxChars(ev))
- return false;
-
- FW_ByteCount maxChars = fEditView->GetMaxChars(ev) - notSelectedChars;
-
- /* See note in Externalize
- // ODIText
- if (FW_SUExistsThenFocus(ev, sourceSU, kODPropContents, kODIntlText))
- internalized = InternalizeIntlText(ev, sourceSU, selectedText);
- else
- */
- // 'TEXT'
- if (FW_SUExistsThenFocus(ev, sourceSU, kODPropContents, FW_CPart::gMacTEXTDataType))
- internalized = InternalizeText(ev, sourceSU, selectedText, maxChars);
-
- if (internalized)
- {
- fInternalizedText = selectedText;
- fEditView->SetSelectedText(ev, selectedText);
-
- // if (storageKind != FW_kPartStorage)
- // fEditView->GetFrame(ev)->GetPart(ev)->PartChanged(ev);
- }
-
- return internalized;
- }
-
- //----------------------------------------------------------------------------------------
- // CEditViewSelContent::ClearSelectedText
- //----------------------------------------------------------------------------------------
-
- void CEditViewSelContent::ClearSelectedText(Environment* ev)
- {
- fEditView->SetSelectedText(ev, FW_CString());
- }
-
- //----------------------------------------------------------------------------------------
- // CEditViewSelContent::UnselectText
- //----------------------------------------------------------------------------------------
-
- void CEditViewSelContent::UnselectText(Environment* ev)
- {
- fEditView->SelectText(ev, 0, 0); // [LSD] should be at selStart
- }
-
- //---------------------------------------------------------------------------------------
- // CEditViewSelContent::IsEmpty
- //---------------------------------------------------------------------------------------
-
- FW_Boolean CEditViewSelContent::IsEmpty(Environment* ev) const
- {
- short startOffset, endOffset;
- fEditView->GetSelectionRange(ev, startOffset, endOffset);
- return (startOffset == endOffset);
- }
-
- //----------------------------------------------------------------------------------------
- // InternalizeText
- //----------------------------------------------------------------------------------------
- // Global function to read text fro a storage unit
-
- FW_Boolean InternalizeText(Environment* ev, ODStorageUnit* storageUnit,
- FW_CString& text, FW_ByteCount maxChars)
- {
- FW_ByteCount textSize = storageUnit->GetSize(ev);
- if (textSize == 0)
- return false;
-
- if (textSize > maxChars)
- textSize = maxChars;
-
- FW_CByteArray byteArray;
- storageUnit->GetValue(ev, textSize, byteArray);
- // byteArray.CopyBuffer(&buffer, textSize);
-
- text = FW_CString((char *)byteArray.GetBuffer(), textSize);
-
- return true;
- }
-
-